package com.ruoyi.bussine.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.ruoyi.bussine.common.config.UrlConfig;
import com.ruoyi.bussine.common.constant.HttpConstant;
import com.ruoyi.bussine.common.enums.integration.PathEnum;
import com.ruoyi.bussine.domain.entity.TbIntegrationLog;
import com.ruoyi.bussine.mapper.TbIntegrationLogMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author zhengyz
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ModuleHttpUtil {

    private final TbIntegrationLogMapper integrationLogMapper;

    private final UrlConfig urlConfig;

    /**
     * get请求，记录请求结果到数据库中
     *
     * @param pathEnum 请求地址枚举
     * @return
     */
    public String get(PathEnum pathEnum) {
        return this.get(pathEnum, null);
    }

    /**
     * get请求，记录请求结果到数据库中
     *
     * @param pathEnum    请求地址枚举
     * @param urlParamMap 请求参数，拼接在url上
     * @return
     */
    public String get(PathEnum pathEnum, Map<String, Object> urlParamMap) {
        TbIntegrationLog tbIntegrationLog = new TbIntegrationLog();
        String url = urlConfig.get(pathEnum.getBaseUrl()) + pathEnum.getPath();
        String paramStr = null;
        if (urlParamMap != null) {
            paramStr = urlParamMap.toString();
        }
        String result = "";
        DateTime requestTime = DateUtil.date();
        try {
            log.info("get请求地址={}，参数={}", url, paramStr);
            result = HttpUtil.get(url, urlParamMap, pathEnum.getTimeOut().getTime());
            log.info("get请求结果={}", result);
            tbIntegrationLog.setResponseBody(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("get请求异常：{}", e.getMessage());
            tbIntegrationLog.setResponseBody(e.getMessage());
            tbIntegrationLog.setResponseCode("500");
        }
        saveLog(tbIntegrationLog, HttpConstant.GET, requestTime, pathEnum, url, paramStr);
        return result;
    }

    /**
     * post请求，记录请求结果到数据库中
     *
     * @param pathEnum 路径枚举
     * @param jsonStr  请求体
     * @return
     */
    public String post(PathEnum pathEnum, String jsonStr) {
        return post(pathEnum, null, jsonStr);
    }

    /**
     * post请求，记录请求结果到数据库中
     *
     * @param pathEnum    地址枚举
     * @param urlParamMap 拼接在url上的参数
     * @param jsonStr     json体
     * @return
     */
    public String post(PathEnum pathEnum, Map<String, Object> urlParamMap, String jsonStr) {
        TbIntegrationLog tbIntegrationLog = new TbIntegrationLog();
        String result = "";
        String url = urlConfig.get(pathEnum.getBaseUrl()) + pathEnum.getPath();
        if (urlParamMap != null) {
            url = url + "?" + HttpUtil.toParams(urlParamMap);
        }
        DateTime requestTime = DateUtil.date();
        try {
            log.info("post请求地址={}", url);
            log.info("post请求参数={}", jsonStr);
            result = HttpUtil.post(url, jsonStr, pathEnum.getTimeOut().getTime());
            log.info("post请求结果={}", result);
            tbIntegrationLog.setResponseBody(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("post请求异常：{}", e.getMessage());
            tbIntegrationLog.setResponseBody(e.getMessage());
            tbIntegrationLog.setResponseCode("500");
        }
        saveLog(tbIntegrationLog, HttpConstant.POST, requestTime, pathEnum, url, jsonStr);
        return result;
    }

    /**
     * 记录请求结果到数据库中
     *
     * @param tbIntegrationLog 日志记录表
     * @param method           请求方法
     * @param requestTime      请求时间
     * @param pathEnum         url信息
     * @param url              url
     * @param requestBody      请求体
     */
//    @Async
    private void saveLog(TbIntegrationLog tbIntegrationLog,
                         String method, DateTime requestTime,
                         PathEnum pathEnum, String url, String requestBody) {
        log.info("save integration log url={}", url);
        // 这里应该要异步操作，不阻塞主线程
        DateTime responseTime = DateUtil.date();
        long spendTime = DateUtil.between(requestTime, responseTime, DateUnit.MS);
        tbIntegrationLog.setRequestSystem(pathEnum.getSystem().name());
        tbIntegrationLog.setRequestMethod(method);
        tbIntegrationLog.setRequestPath(url.length() > 220 ? url.substring(0, 220) : url);
        tbIntegrationLog.setRequestBody(requestBody);
        tbIntegrationLog.setRequestTime(requestTime);
        tbIntegrationLog.setResponseTime(responseTime);
        tbIntegrationLog.setSpendTime(spendTime);
        integrationLogMapper.insert(tbIntegrationLog);
        log.info("save integration log success");
    }

    /**
     * post请求，表单格式，记录请求结果到数据库中
     *
     * @param pathEnum
     * @param formParamMap
     * @return
     */
    public String postForWms(PathEnum pathEnum, Map<String, Object> formParamMap) {
        TbIntegrationLog tbIntegrationLog = new TbIntegrationLog();
        String result = null;
        String url = urlConfig.get(pathEnum.getBaseUrl()) + pathEnum.getPath();
        String requestBody = "\"" + HttpUtil.toParams(formParamMap, null, false) + "\"";
        DateTime requestTime = DateUtil.date();
        try {
            log.info("postForWms请求地址={}", url);
            log.info("postForWms请求参数={}", requestBody);
            result = HttpUtil.createPost(url)
                    .header("Content-Type", "application/json")
                    .body(requestBody)
                    .execute()
                    .body();
            log.info("postForWms请求结果={}", result);
            tbIntegrationLog.setResponseBody(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("post form请求异常：{}", e.getMessage());
            tbIntegrationLog.setResponseBody(e.getMessage());
            tbIntegrationLog.setResponseCode("500");
        }
        saveLog(tbIntegrationLog, HttpConstant.POST, requestTime, pathEnum, url, requestBody);
        return result;
    }

    public String postSetHeaders(PathEnum pathEnum, Map<String, String> headerMap, String requestBody) {
        TbIntegrationLog tbIntegrationLog = new TbIntegrationLog();
        String result = null;
        String url = urlConfig.get(pathEnum.getBaseUrl()) + pathEnum.getPath();
        DateTime requestTime = DateUtil.date();
        try {
            log.info("postSetHeaders请求地址={},\n请求头={},\n请求参数={}", url, headerMap, requestBody);
            result = HttpUtil.createPost(url)
                    .headerMap(headerMap, true)
                    .body(requestBody)
                    .execute()
                    .body();
            log.info("postSetHeaders请求结果={}", result);
            tbIntegrationLog.setResponseBody(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("postSetHeaders请求异常：{}", e.getMessage());
            tbIntegrationLog.setResponseBody(e.getMessage());
            tbIntegrationLog.setResponseCode("500");
        }
        saveLog(tbIntegrationLog, HttpConstant.POST, requestTime, pathEnum, url, requestBody);
        return result;
    }

}
